#ifndef TINYXML_INCLUDED
#define TINYXML_INCLUDED

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "tinystr.h"
#define TIXML_STRING    TiXmlString
#define TIXML_SAFE
#define TIXML_SNPRINTF snprintf
#define TIXML_SSCANF   sscanf

class TiXmlDocument;
class TiXmlElement;
class TiXmlComment;
class TiXmlUnknown;
class TiXmlAttribute;
class TiXmlText;
class TiXmlDeclaration;
class TiXmlParsingData;

struct TiXmlCursor {
  TiXmlCursor() {
    Clear();
  }
  void Clear() {
    row = col = -1;
  }

  int row;
  int col;
};

class TiXmlVisitor {
  public:
    virtual ~TiXmlVisitor() {}
    virtual bool VisitEnter( const TiXmlDocument& ) {
      return true;
    }
    virtual bool VisitExit( const TiXmlDocument& ) {
      return true;
    }
    virtual bool VisitEnter( const TiXmlElement&, const TiXmlAttribute* ) {
      return true;
    }
    virtual bool VisitExit( const TiXmlElement& ) {
      return true;
    }
    virtual bool Visit( const TiXmlDeclaration& ) {
      return true;
    }
    virtual bool Visit( const TiXmlText& ) {
      return true;
    }
    virtual bool Visit( const TiXmlComment& ) {
      return true;
    }
    virtual bool Visit( const TiXmlUnknown& ) {
      return true;
    }
};

enum {
  TIXML_SUCCESS,
  TIXML_NO_ATTRIBUTE,
  TIXML_WRONG_TYPE
};

enum TiXmlEncoding {
  TIXML_ENCODING_UNKNOWN,
  TIXML_ENCODING_UTF8,
  TIXML_ENCODING_LEGACY
};

const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;

class TiXmlBase {
    friend class TiXmlNode;
    friend class TiXmlElement;
    friend class TiXmlDocument;
  public:
    TiXmlBase() : userData( 0 ) {}
    virtual ~TiXmlBase() {}
    virtual void Print( FILE* cfile, int depth ) const = 0;
    static void SetCondenseWhiteSpace( bool condense ) {
      condenseWhiteSpace = condense;
    }
    static bool IsWhiteSpaceCondensed() {
      return condenseWhiteSpace;
    }
    int Row() const {
      return location.row + 1;
    }
    int Column() const {
      return location.col + 1;
    }
    void  SetUserData( void* user ) {
      userData = user;
    }
    void* GetUserData() {
      return userData;
    }
    const void* GetUserData() const {
      return userData;
    }
    static const int utf8ByteTable[256];
    virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) = 0;
    static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );

    enum {
      TIXML_NO_ERROR = 0,
      TIXML_ERROR,
      TIXML_ERROR_OPENING_FILE,
      TIXML_ERROR_PARSING_ELEMENT,
      TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
      TIXML_ERROR_READING_ELEMENT_VALUE,
      TIXML_ERROR_READING_ATTRIBUTES,
      TIXML_ERROR_PARSING_EMPTY,
      TIXML_ERROR_READING_END_TAG,
      TIXML_ERROR_PARSING_UNKNOWN,
      TIXML_ERROR_PARSING_COMMENT,
      TIXML_ERROR_PARSING_DECLARATION,
      TIXML_ERROR_DOCUMENT_EMPTY,
      TIXML_ERROR_EMBEDDED_NULL,
      TIXML_ERROR_PARSING_CDATA,
      TIXML_ERROR_DOCUMENT_TOP_ONLY,
      TIXML_ERROR_STRING_COUNT
    };

  protected:

    static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
    inline static bool IsWhiteSpace( char c ) {
      return ( isspace( ( unsigned char ) c ) || c == '\n' || c == '\r' );
    }
    inline static bool IsWhiteSpace( int c ) {
      if( c < 256 ) {
        return IsWhiteSpace( ( char ) c );
      }
      return false;
    }
    static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
    static const char* ReadText( const char* in, TIXML_STRING* text, bool ignoreWhiteSpace,
                                 const char* endTag, bool ignoreCase, TiXmlEncoding encoding );
    static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
    inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) {
      assert( p );
      if( encoding == TIXML_ENCODING_UTF8 ) {
        *length = utf8ByteTable[ *( ( const unsigned char* )p ) ];
        assert( *length >= 0 && *length < 5 );
      } else { *length = 1; }
      if( *length == 1 ) {
        if( *p == '&' ) {
          return GetEntity( p, _value, length, encoding );
        }
        *_value = *p;
        return p + 1;
      } else if( *length ) {
        for( int i = 0; p[i] && i < *length; ++i ) {
          _value[i] = p[i];
        }
        return p + ( *length );
      } else { return 0; }
    }

    static bool StringEqual( const char* p, const char* endTag, bool ignoreCase, TiXmlEncoding encoding );

    static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
    TiXmlCursor location;
    void* userData;
    static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
    static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
    inline static int ToLower( int v, TiXmlEncoding encoding ) {
      if( encoding == TIXML_ENCODING_UTF8 ) {
        if( v < 128 ) {
          return tolower( v );
        }
        return v;
      } else { return tolower( v ); }
    }
    static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );

  private:
    TiXmlBase( const TiXmlBase& );
    void operator=( const TiXmlBase& base );
    struct Entity {
      const char* str;
      unsigned int strLength;
      char chr;
    };
    enum {
      NUM_ENTITY = 5,
      MAX_ENTITY_LENGTH = 6

    };
    static Entity entity[ NUM_ENTITY ];
    static bool condenseWhiteSpace;
};

class TiXmlNode : public TiXmlBase {
    friend class TiXmlDocument;
    friend class TiXmlElement;
  public:
    enum NodeType {
      TINYXML_DOCUMENT,
      TINYXML_ELEMENT,
      TINYXML_COMMENT,
      TINYXML_UNKNOWN,
      TINYXML_TEXT,
      TINYXML_DECLARATION,
      TINYXML_TYPECOUNT
    };

    virtual ~TiXmlNode();
    const char *Value() const {
      return value.c_str();
    }
    const TIXML_STRING& ValueTStr() const {
      return value;
    }
    void SetValue( const char * _value ) {
      value = _value;
    }
    void Clear();
    TiXmlNode* Parent() {
      return parent;
    }
    const TiXmlNode* Parent() const {
      return parent;
    }
    const TiXmlNode* FirstChild() const {
      return firstChild;
    }
    TiXmlNode* FirstChild() {
      return firstChild;
    }
    const TiXmlNode* FirstChild( const char * value ) const;
    TiXmlNode* FirstChild( const char * _value ) {
      return const_cast< TiXmlNode* >( ( const_cast< const TiXmlNode* >( this ) )->FirstChild( _value ) );
    }
    const TiXmlNode* LastChild() const  {
      return lastChild;
    }
    TiXmlNode* LastChild()  {
      return lastChild;
    }

    const TiXmlNode* LastChild( const char * value ) const;
    TiXmlNode* LastChild( const char * _value ) {
      return const_cast< TiXmlNode* >( ( const_cast< const TiXmlNode* >( this ) )->LastChild( _value ) );
    }
    const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
    TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
      return const_cast< TiXmlNode* >( ( const_cast< const TiXmlNode* >( this ) )->IterateChildren( previous ) );
    }

    const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
    TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
      return const_cast< TiXmlNode* >( ( const_cast< const TiXmlNode* >( this ) )->IterateChildren( _value, previous ) );
    }
    TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
    TiXmlNode* LinkEndChild( TiXmlNode* addThis );
    TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
    TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
    TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
    bool RemoveChild( TiXmlNode* removeThis );
    const TiXmlNode* PreviousSibling() const {
      return prev;
    }
    TiXmlNode* PreviousSibling() {
      return prev;
    }
    const TiXmlNode* PreviousSibling( const char * ) const;
    TiXmlNode* PreviousSibling( const char *_prev ) {
      return const_cast< TiXmlNode* >( ( const_cast< const TiXmlNode* >( this ) )->PreviousSibling( _prev ) );
    }
    const TiXmlNode* NextSibling() const {
      return next;
    }
    TiXmlNode* NextSibling() {
      return next;
    }
    const TiXmlNode* NextSibling( const char * ) const;
    TiXmlNode* NextSibling( const char* _next ) {
      return const_cast< TiXmlNode* >( ( const_cast< const TiXmlNode* >( this ) )->NextSibling( _next ) );
    }
    const TiXmlElement* NextSiblingElement() const;
    TiXmlElement* NextSiblingElement() {
      return const_cast< TiXmlElement* >( ( const_cast< const TiXmlNode* >( this ) )->NextSiblingElement() );
    }
    const TiXmlElement* NextSiblingElement( const char * ) const;
    TiXmlElement* NextSiblingElement( const char *_next ) {
      return const_cast< TiXmlElement* >( ( const_cast< const TiXmlNode* >( this ) )->NextSiblingElement( _next ) );
    }
    const TiXmlElement* FirstChildElement() const;
    TiXmlElement* FirstChildElement() {
      return const_cast< TiXmlElement* >( ( const_cast< const TiXmlNode* >( this ) )->FirstChildElement() );
    }

    const TiXmlElement* FirstChildElement( const char * _value ) const;
    TiXmlElement* FirstChildElement( const char * _value ) {
      return const_cast< TiXmlElement* >( ( const_cast< const TiXmlNode* >( this ) )->FirstChildElement( _value ) );
    }
    int Type() const  {
      return type;
    }
    const TiXmlDocument* GetDocument() const;
    TiXmlDocument* GetDocument() {
      return const_cast< TiXmlDocument* >( ( const_cast< const TiXmlNode* >( this ) )->GetDocument() );
    }
    bool NoChildren() const {
      return !firstChild;
    }
    virtual const TiXmlDocument* ToDocument() const {
      return 0;
    }
    virtual const TiXmlElement* ToElement() const {
      return 0;
    }
    virtual const TiXmlComment* ToComment() const {
      return 0;
    }
    virtual const TiXmlUnknown* ToUnknown() const {
      return 0;
    }
    virtual const TiXmlText* ToText() const {
      return 0;
    }
    virtual const TiXmlDeclaration* ToDeclaration() const {
      return 0;
    }
    virtual TiXmlDocument* ToDocument() {
      return 0;
    }
    virtual TiXmlElement* ToElement() {
      return 0;
    }
    virtual TiXmlComment* ToComment() {
      return 0;
    }
    virtual TiXmlUnknown* ToUnknown() {
      return 0;
    }
    virtual TiXmlText* ToText() {
      return 0;
    }
    virtual TiXmlDeclaration* ToDeclaration() {
      return 0;
    }
    virtual TiXmlNode* Clone() const = 0;
    virtual bool Accept( TiXmlVisitor* visitor ) const = 0;

  protected:
    TiXmlNode( NodeType _type );
    void CopyTo( TiXmlNode* target ) const;
    TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
    TiXmlNode* parent;
    NodeType type;
    TiXmlNode* firstChild;
    TiXmlNode* lastChild;
    TIXML_STRING value;
    TiXmlNode* prev;
    TiXmlNode* next;

  private:
    TiXmlNode( const TiXmlNode& );
    void operator=( const TiXmlNode& base );
};

class TiXmlAttribute : public TiXmlBase {
    friend class TiXmlAttributeSet;
  public:
    TiXmlAttribute() : TiXmlBase() {
      document = 0;
      prev = next = 0;
    }
    TiXmlAttribute( const char * _name, const char * _value ) {
      name = _name;
      value = _value;
      document = 0;
      prev = next = 0;
    }

    const char* Name()  const   {
      return name.c_str();
    }
    const char* Value() const   {
      return value.c_str();
    }
    int IntValue() const;
    double DoubleValue() const;
    const TIXML_STRING& NameTStr() const {
      return name;
    }
    int QueryIntValue( int* _value ) const;
    int QueryDoubleValue( double* _value ) const;
    void SetName( const char* _name ) {
      name = _name;
    }
    void SetValue( const char* _value ) {
      value = _value;
    }
    void SetIntValue( int _value );
    void SetDoubleValue( double _value );
    const TiXmlAttribute* Next() const;
    TiXmlAttribute* Next() {
      return const_cast< TiXmlAttribute* >( ( const_cast< const TiXmlAttribute* >( this ) )->Next() );
    }

    const TiXmlAttribute* Previous() const;
    TiXmlAttribute* Previous() {
      return const_cast< TiXmlAttribute* >( ( const_cast< const TiXmlAttribute* >( this ) )->Previous() );
    }

    bool operator==( const TiXmlAttribute& rhs ) const {
      return rhs.name == name;
    }
    bool operator<( const TiXmlAttribute& rhs )  const {
      return name < rhs.name;
    }
    bool operator>( const TiXmlAttribute& rhs )  const {
      return name > rhs.name;
    }
    virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
    virtual void Print( FILE* cfile, int depth ) const {
      Print( cfile, depth, 0 );
    }
    void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
    void SetDocument( TiXmlDocument* doc ) {
      document = doc;
    }

  private:
    TiXmlAttribute( const TiXmlAttribute& );
    void operator=( const TiXmlAttribute& base );
    TiXmlDocument*  document;
    TIXML_STRING name;
    TIXML_STRING value;
    TiXmlAttribute* prev;
    TiXmlAttribute* next;
};

class TiXmlAttributeSet {
  public:
    TiXmlAttributeSet();
    ~TiXmlAttributeSet();
    void Add( TiXmlAttribute* attribute );
    void Remove( TiXmlAttribute* attribute );
    const TiXmlAttribute* First() const {
      return ( sentinel.next == &sentinel ) ? 0 : sentinel.next;
    }
    TiXmlAttribute* First() {
      return ( sentinel.next == &sentinel ) ? 0 : sentinel.next;
    }
    const TiXmlAttribute* Last() const    {
      return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev;
    }
    TiXmlAttribute* Last() {
      return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev;
    }
    TiXmlAttribute* Find( const char* _name ) const;
    TiXmlAttribute* FindOrCreate( const char* _name );
  private:
    TiXmlAttributeSet( const TiXmlAttributeSet& );
    void operator=( const TiXmlAttributeSet& );
    TiXmlAttribute sentinel;
};

class TiXmlElement : public TiXmlNode {
  public:
    TiXmlElement( const char * in_value );
    TiXmlElement( const TiXmlElement& );
    TiXmlElement& operator=( const TiXmlElement& base );
    virtual ~TiXmlElement();
    const char* Attribute( const char* name ) const;
    const char* Attribute( const char* name, int* i ) const;
    const char* Attribute( const char* name, double* d ) const;
    int QueryIntAttribute( const char* name, int* _value ) const;
    int QueryUnsignedAttribute( const char* name, unsigned* _value ) const;
    int QueryBoolAttribute( const char* name, bool* _value ) const;
    int QueryDoubleAttribute( const char* name, double* _value ) const;
    int QueryFloatAttribute( const char* name, float* _value ) const {
      double d;
      int result = QueryDoubleAttribute( name, &d );
      if( result == TIXML_SUCCESS ) {
        *_value = ( float )d;
      }
      return result;
    }
    void SetAttribute( const char* name, const char * _value );
    void SetAttribute( const char * name, int value );
    void SetDoubleAttribute( const char * name, double value );
    void RemoveAttribute( const char * name );
    const TiXmlAttribute* FirstAttribute() const  {
      return attributeSet.First();
    }
    TiXmlAttribute* FirstAttribute() {
      return attributeSet.First();
    }
    const TiXmlAttribute* LastAttribute() const {
      return attributeSet.Last();
    }
    TiXmlAttribute* LastAttribute() {
      return attributeSet.Last();
    }
    const char* GetText() const;
    virtual TiXmlNode* Clone() const;
    virtual void Print( FILE* cfile, int depth ) const;
    virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
    virtual const TiXmlElement* ToElement() const {
      return this;
    }
    virtual TiXmlElement* ToElement() {
      return this;
    }
    virtual bool Accept( TiXmlVisitor* visitor ) const;
  protected:
    void CopyTo( TiXmlElement* target ) const;
    void ClearThis();
    const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
  private:
    TiXmlAttributeSet attributeSet;
};

class TiXmlComment : public TiXmlNode {
  public:
    TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
    TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
      SetValue( _value );
    }
    TiXmlComment( const TiXmlComment& );
    TiXmlComment& operator=( const TiXmlComment& base );
    virtual ~TiXmlComment() {}
    virtual TiXmlNode* Clone() const;
    virtual void Print( FILE* cfile, int depth ) const;
    virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
    virtual const TiXmlComment*  ToComment() const  {
      return this;
    }
    virtual bool Accept( TiXmlVisitor* visitor ) const;
  protected:
    void CopyTo( TiXmlComment* target ) const;
  private:

};

class TiXmlText : public TiXmlNode {
    friend class TiXmlElement;
  public:
    TiXmlText( const char * initValue ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) {
      SetValue( initValue );
      cdata = false;
    }
    virtual ~TiXmlText() {}
    TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) {
      copy.CopyTo( this );
    }
    TiXmlText& operator=( const TiXmlText& base ) {
      base.CopyTo( this );
      return *this;
    }
    virtual void Print( FILE* cfile, int depth ) const;
    bool CDATA() const {
      return cdata;
    }
    void SetCDATA( bool _cdata )  {
      cdata = _cdata;
    }
    virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
    virtual const TiXmlText* ToText() const {
      return this;
    }
    virtual TiXmlText* ToText() {
      return this;
    }
    virtual bool Accept( TiXmlVisitor* content ) const;
  protected :
    virtual TiXmlNode* Clone() const;
    void CopyTo( TiXmlText* target ) const;
    bool Blank() const;
  private:
    bool cdata;
};

class TiXmlDeclaration : public TiXmlNode {
  public:
    TiXmlDeclaration()   : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
    TiXmlDeclaration( const char* _encoding, const char* _standalone );
    TiXmlDeclaration( const TiXmlDeclaration& copy );
    TiXmlDeclaration& operator=( const TiXmlDeclaration& copy );
    virtual ~TiXmlDeclaration() {}
    const char *Encoding() const {
      return encoding.c_str();
    }
    const char *Standalone() const {
      return standalone.c_str();
    }
    virtual TiXmlNode* Clone() const;
    virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
    virtual void Print( FILE* cfile, int depth ) const {
      Print( cfile, depth, 0 );
    }
    virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
    virtual const TiXmlDeclaration* ToDeclaration() const {
      return this;
    }
    virtual TiXmlDeclaration* ToDeclaration() {
      return this;
    }
    virtual bool Accept( TiXmlVisitor* visitor ) const;
  protected:
    void CopyTo( TiXmlDeclaration* target ) const;
  private:
    TIXML_STRING encoding;
    TIXML_STRING standalone;
};

class TiXmlUnknown : public TiXmlNode {
  public:
    TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )  {}
    virtual ~TiXmlUnknown() {}
    TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {
      copy.CopyTo( this );
    }
    TiXmlUnknown& operator=( const TiXmlUnknown& copy ) {
      copy.CopyTo( this );
      return *this;
    }
    virtual TiXmlNode* Clone() const;
    virtual void Print( FILE* cfile, int depth ) const;
    virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
    virtual const TiXmlUnknown* ToUnknown() const {
      return this;
    }
    virtual TiXmlUnknown* ToUnknown() {
      return this;
    }
    virtual bool Accept( TiXmlVisitor* content ) const;
  protected:
    void CopyTo( TiXmlUnknown* target ) const;
  private:
};

class TiXmlDocument : public TiXmlNode {
  public:
    TiXmlDocument();
    TiXmlDocument( const char * documentName );
    TiXmlDocument( const TiXmlDocument& copy );
    TiXmlDocument& operator=( const TiXmlDocument& copy );
    virtual ~TiXmlDocument() {}
    bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
    bool SaveFile() const;
    bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
    bool SaveFile( const char * filename ) const;
    bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
    bool SaveFile( FILE* ) const;
    virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
    const TiXmlElement* RootElement() const {
      return FirstChildElement();
    }
    TiXmlElement* RootElement() {
      return FirstChildElement();
    }
    bool Error() const {
      return error;
    }
    const char * ErrorDesc() const  {
      return errorDesc.c_str();
    }
    int ErrorId() const {
      return errorId;
    }
    int ErrorRow() const {
      return errorLocation.row + 1;
    }
    int ErrorCol() const {
      return errorLocation.col + 1;
    }
    void SetTabSize( int _tabsize ) {
      tabsize = _tabsize;
    }
    int TabSize() const {
      return tabsize;
    }
    void ClearError() {
      error = false;
      errorId = 0;
      errorDesc = "";
      errorLocation.row = errorLocation.col = 0;
    }
    void Print() const {
      Print( stdout, 0 );
    }
    virtual void Print( FILE* cfile, int depth = 0 ) const;
    void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
    virtual const TiXmlDocument* ToDocument() const {
      return this;
    }
    virtual TiXmlDocument* ToDocument() {
      return this;
    }
    virtual bool Accept( TiXmlVisitor* content ) const;
  protected :
    virtual TiXmlNode* Clone() const;
  private:
    void CopyTo( TiXmlDocument* target ) const;
    bool error;
    int  errorId;
    TIXML_STRING errorDesc;
    int tabsize;
    TiXmlCursor errorLocation;
    bool useMicrosoftBOM;
};

class TiXmlHandle {
  public:
    TiXmlHandle( TiXmlNode* _node ) {
      this->node = _node;
    }
    TiXmlHandle( const TiXmlHandle& ref ) {
      this->node = ref.node;
    }
    TiXmlHandle operator=( const TiXmlHandle& ref ) {
      if( &ref != this ) {
        this->node = ref.node;
      }
      return *this;
    }
    TiXmlHandle FirstChild() const;
    TiXmlHandle FirstChild( const char * value ) const;
    TiXmlHandle FirstChildElement() const;
    TiXmlHandle FirstChildElement( const char * value ) const;
    TiXmlHandle Child( const char* value, int index ) const;
    TiXmlHandle Child( int index ) const;
    TiXmlHandle ChildElement( const char* value, int index ) const;
    TiXmlHandle ChildElement( int index ) const;
    TiXmlNode* ToNode() const {
      return node;
    }
    TiXmlElement* ToElement() const {
      return ( ( node && node->ToElement() ) ? node->ToElement() : 0 );
    }
    TiXmlText* ToText() const {
      return ( ( node && node->ToText() ) ? node->ToText() : 0 );
    }
    TiXmlUnknown* ToUnknown() const {
      return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 );
    }
    TiXmlNode* Node() const {
      return ToNode();
    }
    TiXmlElement* Element() const {
      return ToElement();
    }
    TiXmlText* Text() const {
      return ToText();
    }
    TiXmlUnknown* Unknown() const {
      return ToUnknown();
    }
  private:
    TiXmlNode* node;
};

class TiXmlPrinter : public TiXmlVisitor {
  public:
    TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
      buffer(), indent( "    " ), lineBreak( "\n" ) {}
    virtual bool VisitEnter( const TiXmlDocument& doc );
    virtual bool VisitExit( const TiXmlDocument& doc );
    virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
    virtual bool VisitExit( const TiXmlElement& element );
    virtual bool Visit( const TiXmlDeclaration& declaration );
    virtual bool Visit( const TiXmlText& text );
    virtual bool Visit( const TiXmlComment& comment );
    virtual bool Visit( const TiXmlUnknown& unknown );
    void SetIndent( const char* _indent ) {
      indent = _indent ? _indent : "" ;
    }
    const char* Indent() {
      return indent.c_str();
    }
    void SetLineBreak( const char* _lineBreak ) {
      lineBreak = _lineBreak ? _lineBreak : "";
    }
    const char* LineBreak() {
      return lineBreak.c_str();
    }
    void SetStreamPrinting() {
      indent = "";
      lineBreak = "";
    }
    const char* CStr() {
      return buffer.c_str();
    }
    size_t Size() {
      return buffer.size();
    }
  private:
    void DoIndent() {
      for( int i = 0; i < depth; ++i ) {
        buffer += indent;
      }
    }
    void DoLineBreak() {
      buffer += lineBreak;
    }
    int depth;
    bool simpleTextPrint;
    TIXML_STRING buffer;
    TIXML_STRING indent;
    TIXML_STRING lineBreak;
};

#ifdef _MSC_VER
#pragma warning( pop )
#endif

#endif
